
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.swing.Timer;

import com.modestmaps.core.Point2f;

import omicronAPI.OmicronAPI;

import processing.core.*;
import processing.net.*;


public class P3Sketch extends PApplet {
	int canvasWidth = 1360; // * 6 = 8160
	int canvasHeight = 384; // * 6 = 2304
	public int scaleFactor = 1;
	int mapZoomLevel = 4;

	TouchListener listener = null;
	OmicronAPI omicronManager = null;
	
	public PFont font = null;
	private float percentHigh = 0;
	public boolean isOnWall;
	public DataManager dataManager;
//	public TouchYearSlider myTouchYearSlider;
	public TouchMap map = null;
	private	TouchRadioButtonGroup mapTypeGroup;
	private TouchButton incButton;
	private TouchButton decButton;
	private TouchButton ZoomInButton;
	private TouchButton ZoomOutButton;
	private boolean nextTouchIsAnchor = false;
	public MultiCatChart Graph1;
	public MultiCatChart Graph2;
	public PieChart fatalitiesPercentage;
	HashMap<Integer, ArrayList<State>> appData;
	private ArrayList<Integer> years;
	private int yearPos = 0;
	StatGenerator generator;
	public CopyOnWriteArrayList<MapCluster> clustersOnMap;
//	Menu
	public MenuButton menu;
	public MenuBox menuBox;
	public boolean menuState = false;
	float menuX,menuY,menuWidth,menuHeight;
	private TouchRadioButtonGroup graphHelper;
	private TouchRadioButtonGroup groupSubgroupHelper;
	public CopyOnWriteArrayList<GraphSubgroup> graph1Groupings;
	public CopyOnWriteArrayList<GraphSubgroup> graph1SubGroupings;
	
	public CopyOnWriteArrayList<GraphSubgroup> graph2Groupings;
	public CopyOnWriteArrayList<GraphSubgroup> graph2SubGroupings;
	private Info detailsCase ;
	public GraphSubgroup mapVariable;
	
	//public HashMap<String,Float> StateNameToFatalityPercent;
	public HashMap<Integer,HashMap<String,Float>> yearToStateToPercent;
	public MapCluster lastSelectedCluster = null;

	public void init() {
		  super.init();
		  // Creates the OmicronAPI object. This is placed in init() since we want to use fullscreen
		  isOnWall = false;

		  omicronManager = new OmicronAPI(this);		  
		  
		  // Removes the title bar for full screen mode (present mode will not work on Cyber-commons wall)
		  // will not work unless converted to pde
		  if(isOnWall){
			  omicronManager.setFullscreen(true);  
		  }
		 
	}

	
	public void setup() {
		// if on the wall set scale to 6
		if(!isOnWall){
			scaleFactor = 1;
		}
		else{
			scaleFactor = 6;
		}
		listener = new TouchListener(this);	
		
		canvasWidth = 1360 * scaleFactor;
		canvasHeight = 384 * scaleFactor;
				
		if(!isOnWall){
			size(canvasWidth, canvasHeight, JAVA2D);
			omicronManager.setTouchListener(listener);
		}
		else{
			noSmooth();
			size(canvasWidth, canvasHeight, P3D); // P3D doesn't work java applets
			omicronManager.setTouchListener(listener);
			omicronManager.ConnectToTracker(7001, 7340, "131.193.77.159");
		}				
		
		 addMouseWheelListener(new MouseWheelListener() { 
			    public void mouseWheelMoved(MouseWheelEvent mwe) { 
			      mouseWheel(mwe.getWheelRotation());
			  }}); 


		background(130);					
		font = createFont("Arial",8*((int)(1.2*scaleFactor)),true);
		textFont(font);			
	
		 clustersOnMap = new CopyOnWriteArrayList<MapCluster>();
		  graph1Groupings = new CopyOnWriteArrayList<GraphSubgroup>();
		  graph1SubGroupings = new CopyOnWriteArrayList<GraphSubgroup>();
		  graph2Groupings = new CopyOnWriteArrayList<GraphSubgroup>();
		  graph2SubGroupings = new CopyOnWriteArrayList<GraphSubgroup>();
		  
		  mapVariable = GraphSubgroup.Fatal;
		  
		  map = new TouchMap(this, scaleFactor);
		  years = new ArrayList<Integer>();
		  years.add(2001);
		  years.add(2002);
		  years.add(2003);
		  years.add(2004);
		  years.add(2005);
		  years.add(2006);
		  years.add(2007);
		  years.add(2008);
		  years.add(2009);
		  years.add(2010);
		  
		yearToStateToPercent = new HashMap<Integer,HashMap<String,Float>>();
		float itemHeight = 17*scaleFactor;
		float itemWidth = 44*scaleFactor;

		
		float largBtnWidth = 64*scaleFactor;
		
		graphHelper = new TouchRadioButtonGroup(this, width*0.75f+(largBtnWidth),  height-(3*itemHeight), true);
		graphHelper.AddItem(new TouchRadioButton(this, "Top Graph", largBtnWidth, itemHeight, 100, 100));
		graphHelper.AddItem(new TouchRadioButton(this, "Bottom Graph", largBtnWidth, itemHeight, 100, 100));
		groupSubgroupHelper = new TouchRadioButtonGroup(this, width*0.75f+(2*largBtnWidth),  height-(3*itemHeight), true);
		groupSubgroupHelper.AddItem(new TouchRadioButton(this, "Grouping", largBtnWidth, itemHeight, 100, 100));
		groupSubgroupHelper.AddItem(new TouchRadioButton(this, "Sub-Grouping", largBtnWidth, itemHeight, 100, 100));
		
		graphHelper.setChecked(0, true);
		groupSubgroupHelper.setChecked(0, true);
		
		mapTypeGroup = new TouchRadioButtonGroup(this, width-(3*itemWidth),  height-(itemHeight), false);
		
		mapTypeGroup.AddItem(new TouchRadioButton(this, MapType.Road.label(), itemWidth, itemHeight, 100, 100));
		mapTypeGroup.AddItem(new TouchRadioButton(this, MapType.Satillite.label(), itemWidth, itemHeight, 100, 100));
		mapTypeGroup.AddItem(new TouchRadioButton(this, MapType.Hybrid.label(), itemWidth, itemHeight, 100, 100));
		detailsCase = new Info(this, width*0.5f+10, 50*scaleFactor, null, scaleFactor,isOnWall);
		
		incButton = new TouchButton(this,"+ year",itemWidth, itemHeight, width-(2*itemWidth),  height-(2*itemHeight));
		decButton = new TouchButton(this,"- year",itemWidth, itemHeight, width-(3*itemWidth),  height-(2*itemHeight));
		ZoomInButton = new TouchButton(this,"Zoom In",itemWidth, itemHeight, width-itemWidth,  height-(3*itemHeight));
		ZoomOutButton= new TouchButton(this,"Zoom Out",itemWidth, itemHeight, width-itemWidth,  height-(2*itemHeight));
		
		menu = new MenuButton(this, "Menu", itemWidth, itemHeight,width-(2*itemWidth), height-(3*itemHeight));
		menuX= canvasWidth/2;
		menuY = canvasHeight - canvasHeight*6/7 - 5*scaleFactor;
		menuWidth = canvasWidth;
		menuHeight = canvasHeight - canvasHeight/7 + 5*scaleFactor;
		menuBox = new MenuBox(this,menuX,menuY,menuWidth,menuHeight,scaleFactor);

		mapTypeGroup.setChecked(0, true);
		
		
		dataManager = new DataManager(sketchPath+"/data/");		 		
		appData = dataManager.data;		
		yearToStateToPercent = dataManager.percentData;
		ArrayList<State> currentStates = appData.get(years.get(yearPos));
		for(State state : currentStates){
			if(percentHigh < yearToStateToPercent.get(years.get(yearPos)).get(state.name)){
				percentHigh =  yearToStateToPercent.get(years.get(yearPos)).get(state.name);
			}
		}
		
		
		generator = new StatGenerator(this,scaleFactor);
		// add state clusters on map
		
		clustersOnMap.clear();
		for(State state : currentStates){
			MapCluster stateCluster = new MapCluster(this,scaleFactor,state);
			for(Integer id : state.caseNumbers){
				stateCluster.insertCase(state.cases.get(id));
			}			
			Float statePercent = yearToStateToPercent.get(years.get(yearPos)).get(state.name);
			stateCluster.percent = statePercent;
			stateCluster.setMaxPercent(percentHigh);			
			clustersOnMap.add(stateCluster);
		}	
		
		
		Graph1 = new MultiCatChart(this,scaleFactor,"Group Comparision 1",0,0,width/2,(height/2)-(20*scaleFactor));
		graph1Groupings.add(GraphSubgroup.Alcohol);
		graph1Groupings.add(GraphSubgroup.NonAlcohol);
		graph1Groupings.add(GraphSubgroup.Female);
		graph1Groupings.add(GraphSubgroup.Male);
		graph1SubGroupings.add(GraphSubgroup.Zeroto6);
		graph1SubGroupings.add(GraphSubgroup.Sixto12);
		graph1SubGroupings.add(GraphSubgroup.Twelveto6);
		graph1SubGroupings.add(GraphSubgroup.SixtoMidnight);

		Graph2 = new MultiCatChart(this,scaleFactor,"Group Comparision 2",0,(height/2),width/2,(height/2));
		graph2Groupings.add(GraphSubgroup.ZeroTo20Age);
		graph2Groupings.add(GraphSubgroup.TwentyTo40Age);
		graph2Groupings.add(GraphSubgroup.FortyTo60Age);
		graph2Groupings.add(GraphSubgroup.SixtyTo80Age);
		graph2Groupings.add(GraphSubgroup.EightyTo100Age);
		graph2SubGroupings.add(GraphSubgroup.Alcohol);
		graph2SubGroupings.add(GraphSubgroup.Drugs);
		graph2SubGroupings.add(GraphSubgroup.Speeding);
		graph2SubGroupings.add(GraphSubgroup.ClearVis);
		
		
		// Set IL as default
		for(MapCluster mc : clustersOnMap){
			if(mc.whichState != null && mc.whichState.name.equalsIgnoreCase("Illinois")){
				// get the first state on the map
				// compared against the USA
				generateStatsForGraph(mc,graphHelper.isChecked(0));
				generateStatsForGraph(mc,false);
				lastSelectedCluster = mc;
				Graph1.title = "Illinois comparative fatalities";
				Graph2.title = "Illinois comparative fatalities";
				break;
			}
		}
		
			
//		myTouchYearSlider = new TouchYearSlider(20,canvasHeight - 50,90,canvasHeight - 30);
		
		fatalitiesPercentage = new PieChart(this, scaleFactor, 0.75f*width, width, 0, 50*scaleFactor);
		fatalitiesPercentage.insertCatagory("Illinois", yearToStateToPercent.get(years.get(yearPos)).get("Illinois"), color(103,192,255));
		fatalitiesPercentage.insertCatagory("United States",1-yearToStateToPercent.get(years.get(yearPos)).get("Illinois"), color(228,202,31));
		//fatalitiesPercentage.insertCatagory("Indiana", 0.10f, color(254,116,33));
		//fatalitiesPercentage.insertCatagory("New York", 0.10f, color(0,175,75));
		//fatalitiesPercentage.insertCatagory("Washington", 0.05f, color(0));
		//fatalitiesPercentage.insertCatagory("Penn", 0.15f, color(45));
		
		
	}

	public void draw() {
		background(170);
		if(!menuState){
			map.draw(); // map is the root, everything should be drawn over it
		}
		
		
		
		
		
		fill(255);
		textAlign(RIGHT);
		textSize(11*scaleFactor);
		text("Selected Year: "+years.get(yearPos),width/2-5*scaleFactor,height/2-(7*scaleFactor)); // only have data for 8, 9
		textSize(8*((int)(1.2*scaleFactor)));
		textAlign(LEFT);
		
		mapTypeGroup.draw();
		
		graphHelper.draw();
		groupSubgroupHelper.draw();
		
		menu.draw();
		
		incButton.draw();
		decButton.draw();
		
		ZoomInButton.draw();
		ZoomOutButton.draw();
		
		Graph1.draw();
		Graph2.draw();
		
		fatalitiesPercentage.draw();
//		myTouchYearSlider.drawSlider();
		
		
		// draw our map clusters
		for(MapCluster mc : clustersOnMap){
			if(isOnMap(mc)){
				// then draw it
				
				if(map.getZoomLevel() != mapZoomLevel){
					mapZoomLevel = map.getZoomLevel();					
					//mc.percent = getFatalPercent(mc,map.getZoomLevel());
				}	
				mc.zoomLevelChange(mapZoomLevel);
				Point2f s = map.getPosByCoord(mc.avg_Latitude, mc.avg_Longitude);
				mc.draw(s.x, s.y);
			}
		}		
		detailsCase.draw();
			
		if(menuState){
			menuBox.drawbox(menuState,scaleFactor);
			//menuBox.drawButtons();
		}
		// For event and fullscreen processing, this must be called in draw()
		omicronManager.process();
	}
	void mouseWheel(int delta) {
		
		float sc = 1.0f;
		if (delta > 0) {
			//this is zoom out
			//mapZoomLevel-=1;
			sc = 1.0f/1.05f;
		}
		else if (delta < 0) { 
			// this is zoom in
			//mapZoomLevel+=1;
			sc = 1.05f;			 
		}						
		  float mx = (mouseX - map.getOffsetX()) - map.getWidth()/2;
		  float my = (mouseY - map.getOffsetY()) - map.getHeight()/2;
		  map.map.tx -= mx/map.map.sc;
		  map.map.ty -= my/map.map.sc;
		  map.map.sc *= sc;
		  map.map.tx += mx/map.map.sc;
		  map.map.ty += my/map.map.sc;
		
		
		if(mapZoomLevel != map.getZoomLevel()){
			mapZoomLevel = map.getZoomLevel();
			System.out.println("ZoomLevel: "+mapZoomLevel);
			if(mapZoomLevel >= 0 && mapZoomLevel <= 7){
				clustersOnMap.clear();
				ArrayList<State> currentStates = appData.get(years.get(yearPos));
				for(State state : currentStates){
					MapCluster newState = new MapCluster(this,scaleFactor,state);				
					for(Integer id : state.caseNumbers){
						newState.insertCase(state.cases.get(id));
					}
					newState.percent = yearToStateToPercent.get(years.get(yearPos)).get(state.name);
					newState.setMaxPercent(percentHigh);
					clustersOnMap.add(newState);
				}
			}
			
			if(mapZoomLevel >= 8 && mapZoomLevel <= 11){
				clustersOnMap.clear();
				ArrayList<State> currentStates = appData.get(years.get(yearPos));			
				for(State state : currentStates){
					//MapCluster newState = new MapCluster(this,scaleFactor, state);
					//for(Integer id : state.caseNumbers){
					//	newState.insertCase(state.cases.get(id));
					//}
					//newState.percent = StateNameToFatalityPercent.get(state.name);
					//newState.setMaxPercent(percentHigh);
					//if(isOnMap(newState)){
						clustersOnMap.addAll(generator.getClusterByCountyGivenState(state));
					//}			
				}
			}	
			if(mapZoomLevel > 11){
				clustersOnMap.clear();
				ArrayList<State> currentStates = appData.get(years.get(yearPos));
				for(State state : currentStates){
					MapCluster newState = new MapCluster(this,scaleFactor, state);
					for(Integer id : state.caseNumbers){
						newState.insertCase(state.cases.get(id));
					}
					newState.percent = yearToStateToPercent.get(years.get(yearPos)).get(state.name);
					for(Case c : newState.Cases){
						MapCluster crash = new MapCluster(this,scaleFactor,state);
						crash.insertCase(c);
						crash.setColor(color(235, 104, 53));
						clustersOnMap.add(crash);
					}		
				}
			
			}
		}
		
		
		
		
		

	}	
	


	// NOTE: Mouse pressed, dragged, and released events will also trigger these
	// using an ID of -1 and an xWidth and yWidth value of 10.
	void touchDown(int ID, float xPos, float yPos, float xWidth, float yWidth) {		
		if(xPos > map.borderx1 && map.borderx2 > xPos && map.bordery1 < yPos && map.bordery2 > yPos){
			map.touchDown(ID, xPos, yPos, xWidth, yWidth);
		}		
		touchHandler(xPos,yPos);

		
	}// touchDown

	void touchMove(int ID, float xPos, float yPos, float xWidth, float yWidth) {
		if(xPos > map.borderx1 && map.borderx2 > xPos && map.bordery1 < yPos && map.bordery2 > yPos){
			map.touchMove(ID, xPos, yPos, xWidth, yWidth);
		}
		

	}// touchMove

	void touchUp(int ID, float xPos, float yPos, float xWidth, float yWidth) {
		if(xPos > map.borderx1 && map.borderx2 > xPos && map.bordery1 < yPos && map.bordery2 > yPos){
			map.touchUp(ID, xPos, yPos, xWidth, yWidth);
		}
		
	}// touchUp
	
	
	public boolean isOnMap(MapCluster cluster){
		float latitude = cluster.avg_Latitude;
		float longitude = cluster.avg_Longitude;
		Point2f sl = map.getPosByCoord(latitude, longitude);
		float xPos = sl.x;
		float yPos = sl.y;
		boolean isPastLeft = map.borderx1 <= (xPos - cluster.radius);
		boolean isBeforeRight = map.borderx2 >= (xPos + cluster.radius);
		boolean isAfterTop = map.bordery1 <= (yPos - cluster.radius);
		boolean isBeforeBottom = map.bordery2 >= (yPos + cluster.radius); 
		return isPastLeft && isBeforeRight && isAfterTop && isBeforeBottom;
	}
	
	void touchHandler(float xPos, float yPos){
		mapZoomLevel = map.getZoomLevel();

		int selectedIndex = mapTypeGroup.TouchHandler(xPos, yPos);
		if(selectedIndex > -1){
			switch(selectedIndex){
			case 0:
				map.SetProvider(MapType.Road);				
				break;
			case 1:
				map.SetProvider(MapType.Satillite);
				break;
			case 2:
				map.SetProvider(MapType.Hybrid);
				break;
			default:
					break;
			}				
		}
		if(ZoomInButton.Clicked(xPos, yPos)){
			map.zoomIn();
			adjustClusters();
		}
		if(ZoomOutButton.Clicked(xPos, yPos)){
			map.zoomOut();
			adjustClusters();
		}
		//handle touches on clusters
		if(!menuState){
			for(MapCluster mc : clustersOnMap){
				if(isOnMap(mc)){
					// then handle the touch
					if(mc.touchHandler(xPos, yPos)){
						//System.out.println("("+xPos+","+yPos+") r="+mc.radius);
						if(mc.whichState != null){
							System.out.println(mc.whichState.name);
						}
						lastSelectedCluster = mc;
						fill(0,180,10,90);
						//rect(xPos-mc.radius,yPos-mc.radius,xPos+mc.radius,yPos+mc.radius);
						//mc.percent = getFatalPercent(mc,map.getZoomLevel());
						if(mapZoomLevel >= 0 && mapZoomLevel <= 7){
							fatalitiesPercentage.catagories.clear();
							fatalitiesPercentage.insertCatagory(mc.whichState.name, yearToStateToPercent.get(years.get(yearPos)).get(mc.whichState.name), color(103,192,255));
							fatalitiesPercentage.insertCatagory("United States",1-yearToStateToPercent.get(years.get(yearPos)).get(mc.whichState.name), color(228,202,31));
							generateStatsForGraph(mc,graphHelper.isChecked(0));
						}
						else if(mapZoomLevel >= 8 && mapZoomLevel <= 11){
							fatalitiesPercentage.catagories.clear();
							fatalitiesPercentage.insertCatagory(mc.Cases.get(0).county, mc.percent, color(103,192,255));
							fatalitiesPercentage.insertCatagory(mc.whichState.name,1-mc.percent, color(228,202,31));
							generateStatsForGraph(mc,graphHelper.isChecked(0));
						}
						else{
							// TODO display details page
							detailsCase  = new Info(this,width*0.5f+10,50*scaleFactor, mc.Cases.get(0), scaleFactor, isOnWall);
							
						}
						
						break;
					}					
				}
			}
		}
		
		
		
		
		if(menu.Clicked(xPos, yPos)){			
			menuState = !menuState;
		}
		
		graphHelper.TouchHandler(xPos, yPos);
		groupSubgroupHelper.TouchHandler(xPos, yPos);
		if(incButton.Clicked(xPos, yPos)){
			// TODO fix these
			inc_year();		
		}
		if(decButton.Clicked(xPos, yPos)){
			dec_year();
		}
		
		
		if(menuState){
			// check to see if a
			// TODO button was hit and add the filters/remove them
			MenuResult res = menuBox.touchHandler(xPos, yPos);
			if(res.add > -1){
				// something was hit				
				if(graphHelper.isChecked(0) && groupSubgroupHelper.isChecked(0)){
					addOrRemoveFilter(graph1Groupings, res, 1);
				}
				else if(graphHelper.isChecked(1) && groupSubgroupHelper.isChecked(0)){
					addOrRemoveFilter(graph2Groupings, res, 2);
				}
				else if(graphHelper.isChecked(0) && groupSubgroupHelper.isChecked(1)){
					addOrRemoveFilter(graph1SubGroupings, res, 1);
				}
				else if(graphHelper.isChecked(1) && groupSubgroupHelper.isChecked(1)){
					addOrRemoveFilter(graph2SubGroupings, res, 2);
				}
			}

		}
	
		
	}


	private void adjustClusters(){
		mapZoomLevel = map.getZoomLevel();
		System.out.println("ZoomLevel: "+mapZoomLevel);
		if(mapZoomLevel >= 0 && mapZoomLevel <= 7){
			clustersOnMap.clear();
			ArrayList<State> currentStates = appData.get(years.get(yearPos));
			for(State state : currentStates){
				MapCluster newState = new MapCluster(this,scaleFactor,state);				
				for(Integer id : state.caseNumbers){
					newState.insertCase(state.cases.get(id));
				}
				newState.percent = yearToStateToPercent.get(years.get(yearPos)).get(state.name);
				newState.setMaxPercent(percentHigh);
				clustersOnMap.add(newState);
			}
		}
		
		if(mapZoomLevel >= 8 && mapZoomLevel <= 11){
			clustersOnMap.clear();
			ArrayList<State> currentStates = appData.get(years.get(yearPos));			
			for(State state : currentStates){
				//MapCluster newState = new MapCluster(this,scaleFactor, state);
				//for(Integer id : state.caseNumbers){
				//	newState.insertCase(state.cases.get(id));
				//}
				//newState.percent = StateNameToFatalityPercent.get(state.name);
				//newState.setMaxPercent(percentHigh);
				//if(isOnMap(newState)){
					clustersOnMap.addAll(generator.getClusterByCountyGivenState(state));
				//}			
			}
		}	
		if(mapZoomLevel > 11){
			clustersOnMap.clear();
			ArrayList<State> currentStates = appData.get(years.get(yearPos));
			for(State state : currentStates){
				MapCluster newState = new MapCluster(this,scaleFactor, state);
				for(Integer id : state.caseNumbers){
					newState.insertCase(state.cases.get(id));
				}
				newState.percent = yearToStateToPercent.get(years.get(yearPos)).get(state.getName());
				for(Case c : newState.Cases){
					MapCluster crash = new MapCluster(this,scaleFactor,state);
					crash.insertCase(c);
					crash.setColor(color(235, 104, 53));
					clustersOnMap.add(crash);
				}		
			}
		
		}
	}
	
	private void addOrRemoveFilter(CopyOnWriteArrayList<GraphSubgroup> graphFilters, MenuResult res, int graph){
		if(res.add == 0){
			// that means to add the filter
			
			if(!graphFilters.contains(res.subgroup) && graphFilters.size() < 5){
				if(graph == 1){
					if(!graph1Groupings.contains(res.subgroup) && !graph1SubGroupings.contains(res.subgroup)){
						graphFilters.add(res.subgroup);
					}
				}
				else if(graph == 2){
					if(!graph2Groupings.contains(res.subgroup) && !graph2SubGroupings.contains(res.subgroup)){
						graphFilters.add(res.subgroup);
					}
				}
			}			
		}
		else{
			// remove the filter
			int position = 0;
			for(GraphSubgroup filter : graphFilters){
				if(filter == res.subgroup){
					graphFilters.remove(position);
					break;
				}
				position++;
			}
		}
		generateStatsForGraph(lastSelectedCluster,graphHelper.isChecked(0));
	}
	
	
	public void generateStatsForGraph(MapCluster cluster, boolean isGraph1){
		// as well as the zoom level determinining to compare against nation, state or county

		
		
		
					// if groupings contained time of day 0-6am, 6-12pm
					// and subgroups contained alcohol, trucks
					// 1. remove the current subgroups and groups in the graph
					// 2. insert new groups by label
					// 3. insert new subgroups, designating colors by position, allow no more than 5
					// 4. for each subgroup, call generator for that given subgroup and groupings
					//		return an array of float, where 0<=float<=100 (for percent), 
					//		keep in mind the zoom level: 
					// 		+( 0-4 is state, 
					// 		+( 5-9 county to state
					// 		+( 10+ is individual case
					// 5. set subgroup float values of the array to graph by using the respective order.
		if(isGraph1){
			if(mapZoomLevel >= 8 && mapZoomLevel <= 11){
				Graph1.title = cluster.Cases.get(0).county.toLowerCase() + " comparative fatalities";
			}
			else if(mapZoomLevel < 8){
				Graph1.title = cluster.whichState.name + " comparative fatalities";
			}			
			float graph1YMax = 0;
			Graph1.resetGraph();
			for(GraphSubgroup var : graph1Groupings){
				Graph1.insertGrouping(var.label());
				int counter = 0;
				for(GraphSubgroup var2 : graph1SubGroupings){							
					switch(counter){
					case 0:
						Graph1.insertSubGroup(var2.label(), color(103,192,255));					
						break;
					case 1:
						Graph1.insertSubGroup(var2.label(), color(254,116,33));
						break;
					case 2:
						Graph1.insertSubGroup(var2.label(), color(0,175,75));
						break;
					case 3:
						Graph1.insertSubGroup(var2.label(), color(228,202,31));
						break;
					case 4:
						Graph1.insertSubGroup(var2.label(), color(0,0,0));
						break;
					}
					float percent = getValByZoom(cluster, mapZoomLevel, var, var2);
					//System.out.println("Graph1: "+var.label()+", "+var2.label()+" = "+percent+"%");
					Graph1.setDataGroupToSubGroup(var, var2, percent);
					if(percent > graph1YMax){
						graph1YMax = percent;
						Graph1.yUnitLabelMax = graph1YMax;
						Graph1.setAxisYInterval((float)(percent)/(float)5);
					}

						
					counter++;
				}			
			}
		}
		else{
			if(mapZoomLevel >= 8 && mapZoomLevel <= 11){
				Graph2.title = cluster.Cases.get(0).county.toLowerCase() + " comparative fatalities";
			}
			else if(mapZoomLevel < 8){
				Graph2.title = cluster.whichState.name + " comparative fatalities";
			}
			float graph2YMax = 0;
			Graph2.resetGraph();
			for(GraphSubgroup var : graph2Groupings){
				Graph2.insertGrouping(var.label());
				int counter = 0;
				for(GraphSubgroup var2 : graph2SubGroupings){							
					switch(counter){
					case 0:
						Graph2.insertSubGroup(var2.label(), color(103,192,255));					
						break;
					case 1:
						Graph2.insertSubGroup(var2.label(), color(254,116,33));
						break;
					case 2:
						Graph2.insertSubGroup(var2.label(), color(0,175,75));
						break;
					case 3:
						Graph2.insertSubGroup(var2.label(), color(228,202,31));
						break;
					case 4:
						Graph2.insertSubGroup(var2.label(), color(0,0,0));
						break;
					}
					float percent = getValByZoom(cluster, mapZoomLevel, var, var2);		
					//System.out.println("Graph2: "+var.label()+", "+var2.label()+" = "+percent+"%");
					Graph2.setDataGroupToSubGroup(var, var2, percent);
					if(percent > graph2YMax){
						graph2YMax = percent;
						Graph2.yUnitLabelMax = graph2YMax;
						Graph2.setAxisYInterval((float)(percent)/(float)5);
					}
					counter++;
				}			
			}
		}
		
		
		
		
		
	}
	public float getFatalPercent(MapCluster s_mc,int zoomLevel){
		if(zoomLevel >= 0 && zoomLevel <= 6){
			// compare against the united states, assume the cluster is a state cluster
			MapCluster unitedStates = new MapCluster(this, scaleFactor, null);			
			for(MapCluster mc : clustersOnMap){
				if(!mc.equals(s_mc)){
					unitedStates.insertCases(mc.Cases);
				}
			}
			return generator.getPercentByFactors(GraphSubgroup.Fatal, null, s_mc, unitedStates, zoomLevel);
		}
		else if(zoomLevel >= 7 && zoomLevel <= 11){
			// compare against state, assume the cluster is a county
			State compare_state = s_mc.whichState;
			MapCluster compared_cluster =  new MapCluster(this,scaleFactor,compare_state);
			for(Integer c_num : compare_state.caseNumbers){
				compared_cluster.insertCase(compare_state.cases.get(c_num));
			}
			return generator.getPercentByFactors(GraphSubgroup.Fatal, null, s_mc, compared_cluster, zoomLevel);
		}
		else{
			return -1;
		}
	}
	public float getValByZoom(MapCluster s_mc,int zoomLevel, GraphSubgroup group, GraphSubgroup subgroup){
		if(zoomLevel >= 0 && zoomLevel <= 7){
			// compare against the united states, assume the cluster is a state cluster
			MapCluster unitedStates = new MapCluster(this, scaleFactor, null);			
			for(MapCluster mc : clustersOnMap){
				if(!mc.equals(s_mc)){
					unitedStates.insertCases(mc.Cases);
				}
			}
			return generator.getPercentByFactors(group, subgroup, s_mc, unitedStates, zoomLevel);
		}
		else if(zoomLevel >= 8 && zoomLevel <= 11){
			// compare against state, assume the cluster is a county
			State compare_state = s_mc.whichState;
			MapCluster compared_cluster =  new MapCluster(this,scaleFactor,compare_state);
			for(Integer c_num : compare_state.caseNumbers){
				compared_cluster.insertCase(compare_state.cases.get(c_num));
			}
			return generator.getPercentByFactors(group, subgroup, s_mc, compared_cluster, zoomLevel);
		}
		else{
			return -1;
		}
	}
	
	public void inc_year(){
		if(yearPos+1 < years.size()){
			
			ArrayList<State> currentStates = appData.get(years.get(yearPos));
			percentHigh = 0;			
			yearPos++;			
			clustersOnMap.clear();
			for(State state : currentStates){
				MapCluster stateCluster = new MapCluster(this,scaleFactor,state);
				for(Integer id : state.caseNumbers){
					stateCluster.insertCase(state.cases.get(id));
				}			
				Float statePercent = yearToStateToPercent.get(years.get(yearPos)).get(state.name);
				stateCluster.percent = statePercent;
				if(percentHigh < statePercent){
					percentHigh =  statePercent;
				}
				stateCluster.setMaxPercent(percentHigh);			
				clustersOnMap.add(stateCluster);
			}				
			generateStatsForGraph(this.lastSelectedCluster,true);
			generateStatsForGraph(this.lastSelectedCluster,false);
		}
	}
	public void dec_year(){
		if(yearPos-1 > -1){
			yearPos--;
			ArrayList<State> currentStates = appData.get(years.get(yearPos));
			clustersOnMap.clear();
			for(State state : currentStates){
				MapCluster stateCluster = new MapCluster(this,scaleFactor,state);
				for(Integer id : state.caseNumbers){
					stateCluster.insertCase(state.cases.get(id));
				}			
				Float statePercent = -1f;
				if(yearToStateToPercent.get(years.get(yearPos)).get(state.name) != null){
					statePercent = yearToStateToPercent.get(years.get(yearPos)).get(state.name);
				}
										
				stateCluster.percent = statePercent;
				stateCluster.setMaxPercent(percentHigh);			
				clustersOnMap.add(stateCluster);
			}	
			generateStatsForGraph(this.lastSelectedCluster,true);
			generateStatsForGraph(this.lastSelectedCluster,false);
		}
	}
	
	
	
}
